<template>
  <van-pull-refresh
    :disabled="isRefreshDisable || disabled"
    v-model="refreshing" @refresh="onRefresh">
    <div
      class="goTop"
      v-if="$scopedSlots.tip">
      <slot
        name="tip"
        v-bind="{gpTop}"
      ></slot>
    </div>
    <div
      v-else
      class="goTop"
      @click="gpTop"
    >{{ tip }}</div>
    <van-list
      ref="vanListRef"
      v-model="loading"
      :finished="finished"
      finished-text="没有更多了"
      @load="onLoad"
      class="list"
    >
      <template #default>
        <slot
          v-for="item in list"
          v-bind="item"></slot>
      </template>
    </van-list>
  </van-pull-refresh>
</template>

<script>
import typeOfUtils from "../../utils/type-of-utils";
import clickCountInTimeDecorator from "../../decorator/clickCountInTimeDecorator";
import anime from "animejs";

export default {
  name: "RefreshList",
  props: {
    req: Function,
    tip:{
      type:String,
      default:'双击回到顶部'
    },
    disabled:{
      type:Boolean,
    },
    firstLoad: { // 组件创建就去加载数据
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      list: [],
      loading: false,
      finished: false,
      pageSize: 10,
      pageNum: 1,
      refreshing: false,
      scrollTop: 0,
      isRefreshDisable:true
    }
  },
  watch: {
    scrollTop: {
      immediate: true,
      handler(newval) {
        if (newval > 0) {
          this.isRefreshDisable = true
        } else {
          this.isRefreshDisable = false
        }
      }
    }
  },
  created() {
    this.finished = !this.firstLoad
  },
  mounted() {
    // 解决滚动条与下拉的冲突
    this.$nextTick(() => {
      const vantList = this.$refs.vanListRef.$el
      this.resolveConflict(vantList)
    })
  },
  methods: {
    @clickCountInTimeDecorator(2)
    gpTop(){
      anime({
        targets: [this.$refs.vanListRef.$el],
        scrollTop: 0,
        easing: 'easeInOutSine'
      })
    },
    /**
     * @description: 下拉刷新和滚动事件冲突
     * @param {*}
     * @return {*}
     */
    resolveConflict(val) {
      const vantList = val
      vantList.addEventListener('touchmove', () => {
        this.scrollTop = vantList.scrollTop
      })
      vantList.addEventListener('touchend', () => {
        this.scrollTop = vantList.scrollTop
      })
    },
    onRefresh() {
      // 清空列表数据
      this.finished = false;
      // 重新加载数据
      this.pageNum = 1
      this.list = [];
      this.onLoad();
    },
    /**
     * 当前位置重新加载
     * 逻辑实现，重头加载到当前位置
     */
    nowLoadAgain() {
      if (this.refreshing) {
        this.list = []
        this.refreshing = false
      }
      this.finished = false
      this.loading = true
      const pageSize = this.pageSize * this.pageNum
      this.req({
        pageSize,
        pageNum: 1
      }).then((list) => {
        if (typeOfUtils.isEmpty(list)) {
          this.finished = true
        } else {
          this.list = list
        }
      }).catch(() => {
        this.finished = false
      }).finally(() => {
        this.loading = false
      })
    },
    onLoad() {
      if (this.refreshing) {
        this.list = [];
        this.refreshing = false;
      }
      this.loading = true
      this.req({
        pageSize: this.pageSize,
        pageNum: this.pageNum
      }).then((list) => {
        if (typeOfUtils.isEmpty(list)) {
          this.finished = true
        } else {
          this.list.push(...list)
        }
      }).catch(() => {
        this.finished = false
      }).finally(() => {
        this.loading = false
        this.pageNum++
      })
    }
  }
}
</script>

<style scoped lang="scss">
@import "../../style/global.module";
$topWordHeight: 46; /*px*/
$topFontSize: 32; /*px*/
.goTop{
  height: px2Rem($topWordHeight);
  line-height: px2Rem($topWordHeight);
  font-size: px2Rem($topFontSize);
  text-align: center;
  background-color: #cccccc;
}
.list{
  height: calc(100% - #{px2Rem($topWordHeight)});
  overflow: auto;
}
</style>
